package com.dayatang.hrm.compensation.domain;

import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Transient;

import org.springframework.context.support.MessageSourceAccessor;

import com.dayatang.commons.domain.InstanceFactory;
import com.dayatang.commons.domain.Value;
import com.dayatang.hrm.compensation.context.CompensationMessageSource;
import com.dayatang.hrm.compensation.domain.exception.CompensationRuntimeException;
import com.dayatang.hrm.staffing.domain.Employee;

/**
 * 薪资数据来源字段
 * 
 * @author chencao
 * 
 */
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorValue("5")
public class SalaryDataSourceProperty extends SalaryParameter {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1230295251932422023L;

	private static SalaryDataSourcePropertyRepository salaryDataSourcePropertyRepository;

	protected static MessageSourceAccessor messages = CompensationMessageSource
			.getAccessor();

	// 属性
	@Column(name = "property_name")
	private String property;

	@ManyToOne
	@JoinColumn(name = "salary_datasource_id")
	private SalaryDataSource salaryDataSource;

	/*
	 * =======================================
	 * 
	 * transient
	 * 
	 * ========================================
	 */
	@Transient
	private SalaryDataSourcePropertySetting latestSetting;

	public SalaryDataSourceProperty() {
		latestSetting = SalaryDataSourcePropertySetting.init(this);
	}

	public static SalaryDataSourcePropertyRepository getSalaryDataSourcePropertyRepository() {
		if (salaryDataSourcePropertyRepository == null) {
			salaryDataSourcePropertyRepository = InstanceFactory
					.getInstance(SalaryDataSourcePropertyRepository.class);
		}
		return salaryDataSourcePropertyRepository;
	}

	public static void setSalaryDataSourcePropertyRepository(
			SalaryDataSourcePropertyRepository salaryDataSourcePropertyRepository) {
		SalaryDataSourceProperty.salaryDataSourcePropertyRepository = salaryDataSourcePropertyRepository;
	}

	public static MessageSourceAccessor getMessages() {
		return messages;
	}

	public static void setMessages(MessageSourceAccessor messages) {
		SalaryDataSourceProperty.messages = messages;
	}

	public String getProperty() {
		return property;
	}

	public void setProperty(String property) {
		if (isNew()) {
			this.property = property;
		} else {
			throw new CompensationRuntimeException(messages.getMessage(
					"SalaryDataSourceProperty.setProperty.couldNotModify",
					"不能修改数据来源的属性。"));
		}
	}

	public SalaryDataSource getSalaryDataSource() {
		return salaryDataSource;
	}

	public void setSalaryDataSource(SalaryDataSource salaryDataSource) {
		if (isNew()) {
			this.salaryDataSource = salaryDataSource;
		} else {
			throw new CompensationRuntimeException(
					messages
							.getMessage(
									"SalaryDataSourceProperty.setSalaryDataSource.couldNotModify",
									"不能修改数据来源属性所属的数据源。"));
		}
	}

	SalaryDataSourcePropertySetting getLatestSetting() {
		return latestSetting;
	}

	void setLatestSetting(SalaryDataSourcePropertySetting latestSetting) {
		this.latestSetting = latestSetting;
	}

	/*
	 * =======================================
	 * 
	 * action
	 * 
	 * ========================================
	 */

	@Override
	protected Value calculateValue(Employee employee, Date fromDate, Date toDate) {
		return getSalaryDataSourcePropertyRepository().calculateValue(this,
				employee, fromDate, toDate);
	}

	public static SalaryDataSourceProperty get(Long id, Date queryDate) {
		SalaryDataSourceProperty property = getSalaryDataSourcePropertyRepository()
				.get(id);
		if (property != null) {
			SalaryDataSourcePropertySetting setting = SalaryDataSourcePropertySetting
					.get(property, queryDate);
			if (setting == null) {
				setting = SalaryDataSourcePropertySetting.init(property);
			}
			property.setLatestSetting(setting);
		}
		return property;
	}

	public static SalaryDataSourceProperty getLatest(Long id) {
		return get(id, new Date());
	}

	public static List<SalaryDataSourceProperty> findBySalaryDataSource(
			SalaryDataSource dataSource, Date queryDate) {
		return getSalaryDataSourcePropertyRepository().findBySalaryDataSource(
				dataSource, queryDate);
	}
}
